<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .cont{width: 1000px;border: solid 1px black;margin: 0 auto;overflow: hidden;}
    .cont .box{float: left;border: solid 1px black;box-sizing: border-box;width: 250px;}
    .cont .box>img{width: 80%;height:200px;display: block;margin: 4px auto;}
    .cont .box .imgs{width: 100%;height: 40px;}
    .cont .box .imgs img{width: 40px;height:40px;float: left;}
    .cont p{margin: 5px 0;}
    .cont p:nth-of-type(1){height: 40px;line-height: 20px;overflow: hidden;}
    .cont .tags{width: 100%;height: 20px;}
    .cont .tags span{float: left;margin: 0 2px;padding: 2px;font-size: 12px;color: #fff;}

    tbody img{width: 40px;height: 40px;}
    tbody input{width: 40px;}
  </style>
</head>
<body>
  <div class="cont"></div>

  <table width="700" border="1">
    <thead>
      <tr>
        <th>全选</th>
        <th>图片</th>
        <th>名称</th>
        <th>数量</th>
        <th>价格</th>
        <th>小计</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      
    </tbody>
    <tfoot>
      <tr>
        <th colspan="2"><input type="checkbox" id="allCheck"><label for="allCheck">全选</label></th>
        <th align="right">总数量：</th>
        <th id="sum">0</th>
        <th align="right">总价：</th>
        <th id="sumPrice">0</th>
        <th>删除全部</th>
      </tr>
    </tfoot>
  </table>
</body>
<script src="./data.js"></script>
<script>
  // 选择器
  const cont = document.querySelector(".cont");
  const tbody = document.querySelector("tbody");

  // 模拟异步获取数据
  setTimeout(()=>{
    // goods为所有商品数据
    // 渲染页面结构
    var str = "";
    for(var i=0;i<goods.length;i++){
      str += `<div class="box" data-id="${goods[i].id}">
                <img src="${goods[i].imgs}" alt="">
                <p>${goods[i].name}</p>
                <p>价格：${goods[i].price}</p>
                <input type="button" class="addCart" value="加入购物车">
            </div>`
    }
    cont.innerHTML = str;
  }, 1);

  // 购物车数据
  const cartData = [];

  // 采用事件委托给页面上暂时不存在的元素绑定事件
  cont.onclick = function(eve){
    if(eve.target.className === "addCart"){
      // 获取当前点击商品的id
      const id = eve.target.parentNode.dataset.id
      // 从原有购物车数据中查看本次点击的商品是否是新商品
      let i=0;
      const flag = cartData.some((val,idx)=>{
        i = idx
        return val.id === id
      })
      if(flag){
        // 如果是老商品，数量++
        cartData[i].num++
      }else{
        let p = 0;
        goods.some(val=>{
          p = val.price;
          return val.id === id;
        });
        // 新商品，直接push
        cartData.push({id, num:1, checked:false, price: p})
      }
    }

    // 准备渲染购物车
    let str = "";
    // 遍历总数据
    goods.forEach(val=>{
      // 遍历购物车数据
      cartData.forEach(val2=>{
        // 比对id
        if(val.id === val2.id){
          // 拼接页面结构
          str += `<tr data-id="${val.id}">
                    <td><input type="checkbox" class="check" ${val2.checked ? 'checked' : ''}></td>
                    <td><img src="${val.imgs}" alt=""></td>
                    <td>${val.name}</td>
                    <td><input type="number" value="${val2.num}"></td>
                    <td>${val.price}</td>
                    <td>${val.price * val2.num}</td>
                    <td>删除</td>
                  </tr>`
        }
      })
    })
    // 放入指定容器
    tbody.innerHTML = str;

    // 判断是否需要全选
    allCheck.checked = cartData.every(val=>val.checked);
    // 计算总数量
    $("#sum").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num : 0), 0);
    // 计算总价
    $("#sumPrice").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num*val.price : 0), 0);
  }

  // 全选的复选框元素
  const allCheck = document.querySelector("#allCheck");
  // 事件委托绑定单个复选框的选中状态切换事件
  tbody.addEventListener("change", function(eve){
    // 找到真正的单个复选框
    if(eve.target.className === "check"){
      // 获取选中状态
      const checked = eve.target.checked;
      // 获取当前商品id
      const id = eve.target.parentNode.parentNode.dataset.id;
      // 同步总购物车数据中的状态信息
      cartData.forEach(val=>{
        if(val.id === id){
          val.checked = checked;
        }
      });
      // 根据总购物车数据中的状态信息，设置全选框的选中状态：所有单个选框的全选为选中，只要有一个未选中，全部未选中
      allCheck.checked = cartData.every(val=>val.checked);
      // 计算总数量
      $("#sum").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num : 0), 0);
      // 计算总价
      $("#sumPrice").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num*val.price : 0), 0);
    }
  })

  // 全选框影响单个复选框
  allCheck.onchange = function(){
    // 同步总购物车数据中的选中状态
    cartData.forEach(val=>{
      val.checked = this.checked;
    });
    // 获取所有的复选框元素
    const checks = document.querySelectorAll(".check");
    // 修改所有元素的选中状态
    [...checks].forEach(val=>{
      val.checked = this.checked;
    })
    // 计算总数量
    $("#sum").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num : 0), 0);
    // 计算总价
    $("#sumPrice").innerHTML = cartData.reduce((prev,val)=>prev + (val.checked ? val.num*val.price : 0), 0);
  }


  // 以上代码转成面向对象语法


  function $(s){
    return document.querySelector(s)
  }

</script>
</html>